(ns mogomogo.core
  (:use
   [compojure.core :only [defroutes GET POST]]
   somnium.congomongo
   [somnium.congomongo.config :only [*mongo-config*]]
   [hiccup.core :only [html h]]
   [hiccup.page-helpers :only [doctype include-js include-css]]
   [hiccup.form-helpers :only [form-to label text-area submit-button]]
   [ring.util.response :only [redirect-after-post]]
   [ring.adapter.jetty :only [run-jetty]]
   ring.middleware.params
   ring.middleware.stacktrace
   ring.middleware.reload
   mogomogo.middleware)
  (:require
   [clojure.string :as str]
   [compojure.route :as route])
  (:import
   [java.text SimpleDateFormat])
  )

(defn split-mongo-url [url]
  (let [matcher (re-matcher #"^.*://(.*?):(.*?)@(.*?):(\d+)/(.*)$" url)]
    (when (.find matcher)
      (zipmap [:match :user :pass :host :port :db] (re-groups matcher)))))

(defn init-mongodb []
  (when (not (connection? *mongo-config*))
    (if-let [mongo-url (get (System/getenv) "MONGOHQ_URL")]
      (let [config (split-mongo-url mongo-url)]
        (println "Initializing mongo @ " mongo-url)
        (mongo! :db (:db config)
                :host (:host config)
                :port (Integer. (:port config)))
        (authenticate (:user config) (:pass config))
        (or (collection-exists? :firstcollection)
            (create-collection! :firstcollection)))
      (mongo! :db "mogomogo") ; local environment
      )))

(defn reset-tweets []
  (drop-coll! :tweets)
  (redirect-after-post "/"))

(defn format-date [tm]
  (.format (SimpleDateFormat. "yyyy/MM/dd HH:mm:ss") tm))

(defn tweet [params]
  (let [tweet (params "tweet")]
    (if (not (str/blank? tweet))
      (insert! :tweets {:text tweet})))
  (redirect-after-post "/"))

(defn layout [title & body]
  (html
   (doctype :html5)
   [:head
    [:meta {:charset "utf-8"}]
    [:title title]
    (include-css "http://fonts.googleapis.com/css?family=Sigmar+One&v1")
    (include-js "http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js")]
   [:body
    [:div {:id "header"}
     [:h1 {:class "container"} "MogoMogo"]]
    [:div {:id "content" :class "container"} body]]))

(defn tweet-form []
  [:div {:id "tweet-form"}
   (form-to [:post "/"]
            (label "tweet" "いま何勉強してる?")
            (text-area "tweet")
            (submit-button "tweet!"))])

(defn display-tweets [tweets]
  [:div {:id "tweets"}
   (map
    (fn [tweet]
      [:div
       [:h2 {:class "tweet"} (h (:text tweet))]
       [:div {:class "timestamp"} (format-date (get-timestamp tweet))]])
    tweets)])

(defn index [tweets]
  (layout "MogoMogo"
          (tweet-form)
          [:div {:class "clear"}]
          (display-tweets tweets)))

(defroutes main-routes
  (GET "/" []
       (init-mongodb)
       (index (fetch :tweets :sort {:_id -1})))
  (POST "/" {params :params} (tweet params))
  (GET "/reset" [] (reset-tweets))
  (route/not-found "<h1>Page Not Found.</h1>"))

(def app
  (-> main-routes
      wrap-params
      wrap-request-logging
      wrap-request-dump
      (wrap-reload '[mogomogo.core])
      wrap-stacktrace
      ))

(defn start-server [port]
  (run-jetty app {:port port}))

(defn -main []
  (let [port (Integer/parseInt (System/getenv "PORT"))]
    (start-server port)))
